package judesart.app.client.ui.admin.artwork;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import judesart.app.client.controller.ArtworkController;
import judesart.app.client.controller.ArtworkControllerAsync;
import judesart.app.client.model.ArtworkModel;
import judesart.app.client.resources.Resources;
import judesart.app.shared.ArtworkShort;
import judesart.app.shared.SearchResult;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class ArtworksPanel extends Composite {
    ArtworkControllerAsync artworkController = GWT.create(ArtworkController.class);
    ArtworkDetailsPanel artworkDetailsPanel;
    private final ArtworkDetailsPanel detailsPanel;
    private final Button btnAddNew;
    private final Grid<BeanModel> grid;
    private final ContentPanel cntntpnlArtworks;
    private final ContentPanel mainPanel;

    public ArtworksPanel() {
        RpcProxy<PagingLoadResult<ArtworkShort>> proxy = new RpcProxy<PagingLoadResult<ArtworkShort>>() {
            @Override
            protected void load(Object loadConfig,
                    final AsyncCallback<PagingLoadResult<ArtworkShort>> callback) {
                Log.debug(" > Load artworks");
                PagingLoadConfig pLoadConfig = (PagingLoadConfig) loadConfig;
                final int offset = pLoadConfig.getOffset();
                artworkController.searchArtworks(offset,
                        pLoadConfig.getLimit(),
                        pLoadConfig.getSortField(),
                        pLoadConfig.getSortDir() == SortDir.ASC,
                        new AsyncCallback<SearchResult<ArtworkShort>>() {
                            @Override
                            public void onFailure(Throwable caught) {
                                callback.onFailure(caught);
                            }

                            @Override
                            public void onSuccess(SearchResult<ArtworkShort> result) {
                                Log.debug("load artworks done ["
                                        + result.getCount() + "]:["
                                        + result.getResults().size() + "]");
                                callback.onSuccess(new BasePagingLoadResult<ArtworkShort>(result.getResults(), offset, result.getCount()));
                            }
                        });
            }
        };

        final PagingLoader<PagingLoadResult<ArtworkShort>> loader = new BasePagingLoader<PagingLoadResult<ArtworkShort>>(proxy, new BeanModelReader());
        loader.setRemoteSort(true);

        ListStore<BeanModel> store = new ListStore<BeanModel>(loader);

        final PagingToolBar toolBar = new PagingToolBar(20);
        toolBar.bind(loader);

        List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
        ColumnConfig image = new ColumnConfig("imageId", "Photo", 150);
        image.setRenderer(new GridCellRenderer<BeanModel>() {
            public Object render(BeanModel model, String property,
                    ColumnData config, int rowIndex, int colIndex,
                    ListStore<BeanModel> store, Grid<BeanModel> grid) {
            	Log.debug("render model");
            	ArtworkShort artwork = model.getBean();
                Long imageId = artwork.getImageId();
            	Log.debug("id [" + artwork.getId() + "] imageId [" + imageId + "]");
                if (imageId != null) {
                    String url = "/image/" + imageId + "_80x80_crop";
                    Log.debug("image url [" + url + "]");
                    return "<img src=" + url + " width=\"100\" />";
                } else {
                    return "";
                }
            }
        });
        columns.add(image);
        columns.add(new ColumnConfig("title", "Title", 150));
        columns.add(new ColumnConfig("type", "Type", 100));
        columns.add(new ColumnConfig("year", "Year", 100));
        columns.add(new ColumnConfig("featured", "Featured", 100));

        ColumnModel cm = new ColumnModel(columns);

        grid = new Grid<BeanModel>(store, cm);
        grid.setStateId("artworkss");
        grid.setStateful(true);
        grid.addListener(Events.Attach,
                new Listener<GridEvent<ArtworkModel>>() {
                    public void handleEvent(GridEvent<ArtworkModel> be) {
                        PagingLoadConfig config = new BasePagingLoadConfig();
                        config.setOffset(0);
                        config.setLimit(20);

                        Map<String, Object> state = grid.getState();
                        if (state.containsKey("offset")) {
                            int offset = (Integer) state.get("offset");
                            int limit = (Integer) state.get("limit");
                            config.setOffset(offset);
                            config.setLimit(limit);
                        }
                        if (state.containsKey("sortField")) {
                            config.setSortField((String) state.get("sortField"));
                            config.setSortDir(SortDir.valueOf((String) state.get("sortDir")));
                        }
                        loader.load(config);
                    }
                });
        grid.setLoadMask(true);
        grid.setBorders(true);
        grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        grid.getSelectionModel().addListener(Events.SelectionChange,
                new Listener<SelectionChangedEvent<BeanModel>>() {
                    public void handleEvent(
                            SelectionChangedEvent<BeanModel> be) {
                        Log.debug("Selection changed event ["
                                + be.getSelection().size() + "].");
                        if (be.getSelection().size() > 0) {
                        	ArtworkShort art = be.getSelection().get(0).getBean();
                            show(art.getId());
                        }
                    }
                });

        ContentPanel panel = new ContentPanel();
        panel.setFrame(false);
        panel.setCollapsible(false);
        panel.setIcon(Resources.ICONS.table());
        panel.setHeaderVisible(false);
        panel.setLayout(new FitLayout());
        panel.add(grid);
        panel.setSize(740, 400);
        panel.setBottomComponent(toolBar);
        grid.setAriaLabelledBy(panel.getId());

        mainPanel = new ContentPanel();
        mainPanel.setHeaderVisible(false);
        mainPanel.setBorders(false);
        mainPanel.setBodyBorder(false);

        cntntpnlArtworks = new ContentPanel();
        cntntpnlArtworks.setButtonAlign(HorizontalAlignment.CENTER);
        cntntpnlArtworks.setFrame(true);
        cntntpnlArtworks.setHeading("Artworks");

        cntntpnlArtworks.add(panel);

        btnAddNew = new Button("Add New");
        cntntpnlArtworks.addButton(btnAddNew);
        btnAddNew.addListener(Events.Select, new Listener<ButtonEvent>() {
            public void handleEvent(ButtonEvent e) {
                addNew();
            }
        });
        mainPanel.add(cntntpnlArtworks);

        detailsPanel = new ArtworkDetailsPanel(this);
        mainPanel.add(detailsPanel);

        initComponent(mainPanel);
        final Timer hideDetailsPanelTimer = new Timer() {
            @Override
            public void run() {
                detailsPanel.hide();
            }
        };
        hideDetailsPanelTimer.schedule(500);
    }

    private void addNew() {
        detailsPanel.open(null);
        cntntpnlArtworks.hide();
        detailsPanel.show();
        mainPanel.layout();
    }

    private void show(Long id) {
        detailsPanel.open(id);
        cntntpnlArtworks.hide();
        detailsPanel.show();
        mainPanel.layout();
    }

    protected void showList() {
        detailsPanel.hide();
        cntntpnlArtworks.show();
        mainPanel.layout();
        grid.getStore().getLoader().load();
    }

}
